package com.cyh;

import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * HashMap是非线程安全的，所以多线程扩容的时候会导致死链的问题。jdk7才会出现，jdk8不会出现但会出现扩容丢数据，所以不要用hashmap, 导致这些的原因是线程不安全。
 * 线程安全的集合类
 *  遗留的线程安全集合如：Hashtable, Vector： 在所有方法上加了synchronized，性能不高
 *  使用Collections装饰的线程安全集合，如：  里面包装了一个如List的自己的类，然后重新调用了它的所有方法，并且每个方法加上synchronized修饰，性能也不高。
 *      Collections.synchronizedCollection
 *      Collections.synchronizedList
 *      Collections.synchronizedMap
 *      Collections.synchronizedSet
 *      Collections.synchronizedNavigableMap
 *      Collections.synchronizedNavigableSet
 *      Collections.synchronizedSortedMap
 *      Collections.synchronizedSortedSet
 *   java.util.concurrent.* 类下面的类也都是线程安全的： 推荐使用
 *        这种类有规律：一般以Blocking、CopyOnWrite、Concurrent开头的类都是线程安全的。
 *        Blocking开头的类：大部分基于锁，并提供用来阻塞的方法: 如BlockingDeque，LinkedBlockingDeque等根据代码提示
 *        CopyOnWrite开头的类：类容器修改开销相对较重，用于读和写，修改时开销大，如CopyOnWriteArrayList等根据代码提示
 *        Concurrent开头的类：如ConcurrentLinkedDeque等根据代码的提示
 *            内部多操作使用cas优化，一般可以提供较高的吞吐量
 *            弱一致性：
 *               遍历时弱一致性，例如，当利用迭代器遍历时，如果容器发生修改，迭代器仍然可以继续进行遍历，这时内容是旧的。
 *               求大小时一致性，size操作未必100%准确，效率也低，最好用isEmpty来检查空
 *               读取弱一致性。可能读取的是旧的数据，所以修改数据时也要小心
 *       注意：这里的安全是指单线程内类的单个方法安全，如get(),put()方法是安全的，但是如果一个线程同时使用get()和put()方法，他就不是安全了。如果加synchronized包裹起来又效率太低。
 *            解决方法：比如ConcurrentHashMap类：将两个操作放入同一个方法：
 *                     如Integer value = map.computeIfAbsent(key, ()->{1}):表示如果缺少一个key,则计算生成一个value，然后将key和value放入map.
 *                     即key值不存在，则value=1.如果key值存在，则返回value。
 *                     但是如何在有key值时，操作也安全呢，可以用累加器：LongAdder value = map.computeIfAbsent(key, (key)->new LongAdder()); value.increment();
 *
 * */
public class Test05 {
    public static void main(String[] args) {

    }
}
